package com.pay.utils.validate.vali_annotation;

import com.pay.utils.validate.vali_util.ValidateCodeEnum;
import com.pay.utils.validate.vali_util.ValidateConstants;
import com.pay.utils.validate.vali_util.ValidateUtil;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;


/**
 * 后台验证 基类
 *
 * @author MENG
 * @version 2019/1/21
 * @see
 */
public class BaseValidate
{
    /**
     * 公共 验证必填字段
     *
     * @return fields  需要验证的field
     */
    protected Map<String, Object> requireField(Field... fields)
        throws IllegalAccessException
    {
        if(fields == null || fields.length == 0)
        {
            fields = this.getClass().getDeclaredFields();
        }

        for (Field field : fields)
        {
            if (field.isAnnotationPresent(RequireField.class))
            {
                RequireField obj = field.getAnnotation(RequireField.class);

                String description = obj.description();// 获取注解描述

                field.setAccessible(true); // 设置属性是可以访问的(私有的也可以)

                Object value = field.get(this);

                if(value == null)
                {
                    return publicReturn(description,field, ValidateCodeEnum.REQUIRE_FIELD);
                }

                if(value instanceof String)
                {
                    if (value == null || "".equals(value.toString()))
                    {
                        return publicReturn(description,field,ValidateCodeEnum.REQUIRE_FIELD);
                    }
                }
                else if(value instanceof List)
                {
                    List list = (List)value;

                    if (value == null || list.size() == 0)
                    {
                        return publicReturn(description,field,ValidateCodeEnum.REQUIRE_FIELD);
                    }
                }

            }
        }

        return ValidateUtil.returnSuccess();
    }



    /**
     * 公共 验证邮箱合法性
     *
     * @return
     */
    protected Map<String, Object> emailIllegal(Field... fields)
        throws IllegalAccessException
    {
        if(fields == null || fields.length == 0)
        {
            fields = this.getClass().getDeclaredFields();
        }

        for (Field field : fields)
        {
            if (field.isAnnotationPresent(EmailIllegal.class))
            {
                EmailIllegal obj = field.getAnnotation(EmailIllegal.class);

                String description = obj.description();// 获取注解描述

                field.setAccessible(true); // 设置属性是可以访问的(私有的也可以)

                Object value = field.get(this);

                //判断非空
                if (value == null || "".equals(value))
                {
//                    return publicReturn(description,field,ValidateCodeEnum.EMAIL_ILLEGAL);
                    return ValidateUtil.returnSuccess();
                }

                //判断 邮箱是否合法
                if (!ValidateUtil.checkEmail(value.toString()))
                {
                    return publicReturn(description,field,ValidateCodeEnum.EMAIL_ILLEGAL);
                }
            }
        }

        return ValidateUtil.returnSuccess();
    }

    /**
     * 公共 验证邮箱合法性
     *
     * @return
     */
    protected Map<String, Object> phoneIllegal(Field... fields)
        throws IllegalAccessException
    {
        if(fields == null || fields.length == 0)
        {
            fields = this.getClass().getDeclaredFields();
        }

        for (Field field : fields)
        {
            if (field.isAnnotationPresent(PhoneIllegal.class))
            {
                PhoneIllegal obj = field.getAnnotation(PhoneIllegal.class);

                String description = obj.description();// 获取注解描述

                field.setAccessible(true); // 设置属性是可以访问的(私有的也可以)

                Object value = field.get(this);

                //判断非空
                if (value == null || "".equals(value))
                {
//                    return publicReturn(description,field,ValidateCodeEnum.EMAIL_ILLEGAL);
                    return ValidateUtil.returnSuccess();
                }

                //判断 邮箱是否合法
                if (!ValidateUtil.checkPhone(value.toString()))
                {
                    return publicReturn(description,field,ValidateCodeEnum.PHONE_ILLEGAL);
                }
            }
        }

        return ValidateUtil.returnSuccess();
    }

    /**
     * 公共 验证字段长度合法性
     *
     * @return
     */
    protected Map<String, Object> lengthIllegal(Field... fields)
        throws IllegalAccessException
    {
        if(fields == null || fields.length == 0)
        {
            fields = this.getClass().getDeclaredFields();
        }

        for (Field field : fields)
        {
            if (field.isAnnotationPresent(LengthIllegal.class))
            {
                LengthIllegal obj = field.getAnnotation(LengthIllegal.class);

                String description = obj.description();// 获取注解描述

                int start = obj.start();//开始长度

                int end = obj.end();//结束长度

                field.setAccessible(true); // 设置属性是可以访问的(私有的也可以)

                Object value = field.get(this);

                //判断是否为空
                if (value == null || "".equals(value))
                {
//                    return publicReturn(description,field,ValidateCodeEnum.LENGTH_ILLEGAL);
                    return ValidateUtil.returnSuccess();
                }

                //判断长度是否合法
                if (value.toString().length() < start || value.toString().length() > end)
                {
                    return publicReturn(description,field,ValidateCodeEnum.LENGTH_ILLEGAL);
                }
            }
        }

        return ValidateUtil.returnSuccess();
    }





    /**
     * 是否是数字 int 类型 和 范围验证
     *
     * @return
     */
    protected Map<String, Object> integerIllegal(Field... fields)
        throws IllegalAccessException
    {
        if(fields == null || fields.length == 0)
        {
            fields = this.getClass().getDeclaredFields();
        }

        for (Field field : fields)
        {
            if (field.isAnnotationPresent(IntegerIllegal.class))
            {
                IntegerIllegal obj = field.getAnnotation(IntegerIllegal.class);

                String description = obj.description();// 获取注解描述

                //数字范围
                int start = obj.start();
                int end = obj.end();


                field.setAccessible(true); // 设置属性是可以访问的(私有的也可以)

                Object value = field.get(this);

                //判断是否为空
                if (value == null || "".equals(value))
                {
//                    return publicReturn(description,field,ValidateCodeEnum.NUMBER_ILLEGAL);
                    return ValidateUtil.returnSuccess();
                }

                //判断是否是数字格式
                int tmp = 0;

                try
                {
                    tmp = Integer.valueOf(value.toString());
                }
                catch (Exception e)
                {
                    return publicReturn(description,field,ValidateCodeEnum.NUMBER_ILLEGAL);
                }


                if (tmp < start || tmp > end)
                {
                    return publicReturn(description,field,ValidateCodeEnum.NUMBER_ILLEGAL);
                }
            }
        }

        return ValidateUtil.returnSuccess();
    }

    /**
     * 是否是数字 double 类型 和 范围验证
     *
     * @return
     */
    protected Map<String, Object> doubleIllegal(Field... fields)
        throws IllegalAccessException
    {
        if(fields == null || fields.length == 0)
        {
            fields = this.getClass().getDeclaredFields();
        }

        for (Field field : fields)
        {
            if (field.isAnnotationPresent(DoubleIllegal.class))
            {
                DoubleIllegal obj = field.getAnnotation(DoubleIllegal.class);

                String description = obj.description();// 获取注解描述

                //数字范围
                double start = obj.start();
                double end = obj.end();


                field.setAccessible(true); // 设置属性是可以访问的(私有的也可以)

                Object value = field.get(this);

                //判断是否为空
                if (value == null || "".equals(value))
                {
//                    return publicReturn(description,field,ValidateCodeEnum.NUMBER_ILLEGAL);
                    return ValidateUtil.returnSuccess();
                }

                //判断是否是数字格式
                double tmp = 0;

                try
                {
                    tmp = Double.valueOf(value.toString());
                }
                catch (Exception e)
                {
                    return publicReturn(description,field,ValidateCodeEnum.NUMBER_ILLEGAL);
                }


                if (tmp < start || tmp > end)
                {
                    return publicReturn(description,field,ValidateCodeEnum.NUMBER_ILLEGAL);
                }
            }
        }

        return ValidateUtil.returnSuccess();
    }


    /**
     * 是否是数字 long 类型 和 范围验证
     *
     * @return
     */
    protected Map<String, Object> longIllegal(Field... fields)
        throws IllegalAccessException
    {
        if(fields == null || fields.length == 0)
        {
            fields = this.getClass().getDeclaredFields();
        }

        for (Field field : fields)
        {
            if (field.isAnnotationPresent(LongIllegal.class))
            {
                LongIllegal obj = field.getAnnotation(LongIllegal.class);

                String description = obj.description();// 获取注解描述

                //数字范围
                long start = obj.start();
                long end = obj.end();


                field.setAccessible(true); // 设置属性是可以访问的(私有的也可以)

                Object value = field.get(this);

                //判断是否为空
                if (value == null || "".equals(value))
                {
//                    return publicReturn(description,field,ValidateCodeEnum.NUMBER_ILLEGAL);
                    return ValidateUtil.returnSuccess();
                }

                //判断是否是数字格式
                long tmp = 0;

                try
                {
                    tmp = Long.valueOf(value.toString());
                }
                catch (Exception e)
                {
                    return publicReturn(description,field,ValidateCodeEnum.NUMBER_ILLEGAL);
                }


                if (tmp < start || tmp > end)
                {
                    return publicReturn(description,field,ValidateCodeEnum.NUMBER_ILLEGAL);
                }
            }
        }

        return ValidateUtil.returnSuccess();
    }

    /**
     * 是否是日期类型
     *
     * @return
     */
    protected Map<String, Object> dateIllegal(Field... fields) throws IllegalAccessException
    {
        if(fields == null || fields.length == 0)
        {
            fields = this.getClass().getDeclaredFields();
        }

        for (Field field : fields)
        {
            if (field.isAnnotationPresent(DateIllegal.class))
            {
                DateIllegal obj = field.getAnnotation(DateIllegal.class);

                String description = obj.description();// 获取注解描述

                //数字范围
                String format = obj.format();

                field.setAccessible(true); // 设置属性是可以访问的(私有的也可以)

                Object value = field.get(this);

                //判断是否为空
                if (value == null || "".equals(value))
                {
//                    return publicReturn(description,field,ValidateCodeEnum.DATE_ILLEGAL);
                    return ValidateUtil.returnSuccess();
                }


                //判断是否是日期格式
                try
                {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);

                    simpleDateFormat.parse(value.toString());
                }
                catch (Exception e)
                {
                    return publicReturn(description,field,ValidateCodeEnum.DATE_ILLEGAL);
                }

            }
        }

        return ValidateUtil.returnSuccess();
    }

    /**
     * 公共ruturn 函数
     * @param description
     * @param field
     * @param ValidateCodeEnum
     * @return
     */
    public Map<String,Object> publicReturn(String description,Field field,ValidateCodeEnum ValidateCodeEnum)
    {
        if (description != null && !"".equals(description))
        {
            return ValidateUtil.returnError(ValidateCodeEnum.getCode(), description);
        }
        else
        {
            return ValidateUtil.returnError(ValidateCodeEnum.getCode(), "字段名 : " + field.getName() + " " + ValidateCodeEnum.getMessage());
        }
    }


    /**
     * 公共验证函数
     *
     * @return
     * @throws IllegalAccessException
     */
    public Map<String, Object> validate() throws IllegalAccessException
    {
        if(!requireField().get(ValidateConstants.RESULT_CODE).equals(ValidateConstants.RESULT_SUCCESS_CODE))
        {
            return requireField();
        }

        if(!lengthIllegal().get(ValidateConstants.RESULT_CODE).equals(ValidateConstants.RESULT_SUCCESS_CODE))
        {
            return lengthIllegal();
        }

        if(!integerIllegal().get(ValidateConstants.RESULT_CODE).equals(ValidateConstants.RESULT_SUCCESS_CODE))
        {
            return integerIllegal();
        }

        if(!doubleIllegal().get(ValidateConstants.RESULT_CODE).equals(ValidateConstants.RESULT_SUCCESS_CODE))
        {
            return doubleIllegal();
        }

        if(!longIllegal().get(ValidateConstants.RESULT_CODE).equals(ValidateConstants.RESULT_SUCCESS_CODE))
        {
            return longIllegal();
        }

        if(!dateIllegal().get(ValidateConstants.RESULT_CODE).equals(ValidateConstants.RESULT_SUCCESS_CODE))
        {
            return dateIllegal();
        }

        if(!emailIllegal().get(ValidateConstants.RESULT_CODE).equals(ValidateConstants.RESULT_SUCCESS_CODE))
        {
            return emailIllegal();
        }

        if(!phoneIllegal().get(ValidateConstants.RESULT_CODE).equals(ValidateConstants.RESULT_SUCCESS_CODE))
        {
            return phoneIllegal();
        }

        return ValidateUtil.returnSuccess();
    }





}
